﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Agr.CQRS.Domain.Events;
using System.Runtime.Serialization.Formatters.Binary;
using Agr.CQRS.Infrastructure.Events;
using System.IO;

namespace Tests.Agr.CQRS.InfraStructure.Events
{
    [TestClass]
    public class When_DomainEvent_Is_Serialized_And_Deserialized_Using_A_StoredDomainEvent
    {
        private DaEvent org;
        private DaEvent result;
        private StoredDomainEvent sde;

        [TestInitialize]
        public void TestInit()
        {
            //Given
            org = new DaEvent { 
                SomeProperty = "This is a property value", 
                AggregateRootId = Guid.NewGuid(),
                Version = 10
            };
            sde = new StoredDomainEvent();

            //When
            sde.WrapEvent(org);
            result = sde.GetEvent() as DaEvent;
        }

        [TestMethod]
        public void Then_All_Properties_Are_Properly_Deserialized()
        {
            Assert.IsNotNull(result);
            Assert.AreEqual(org.AggregateRootId, result.AggregateRootId);
            Assert.AreEqual(org.Version, result.Version);
            Assert.AreEqual(org.SomeProperty, result.SomeProperty);
        }

        [TestMethod]
        public void Then_The_Base_Properties_Are_Not_Serialized_But_Stored_Seperately()
        {
            Assert.AreEqual(org.AggregateRootId, sde.AggregateRootId);
            Assert.AreEqual(org.Version, sde.Version);

            var bf = new BinaryFormatter();
            DaEvent ev;
            using (var ms = new MemoryStream(sde.SerializedEvent))
                ev = bf.Deserialize(ms) as DaEvent;

            Assert.AreEqual(Guid.Empty, ev.AggregateRootId);
            Assert.AreEqual(0, ev.Version);
        }

        [Serializable]
        private class DaEvent : DomainEvent
        {
            public string SomeProperty { get; set; }
        }
    }
}
